-
Notifications
You must be signed in to change notification settings - Fork 1.6k
tls: Introduce OpenSSL #2569
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
tls: Introduce OpenSSL #2569
Conversation
@elcallio please review Are there any functional differences? Is hot reload of certificates supported? Should we support gnutls and openssl in parallel? |
The only major difference between the OpenSSL vs GnuTLS implementation is how the implementation is configured. With OpenSSL, there are 5 new methods that can be used to control it (compared to the single
There may be some other subtler differences, such as OpenSSL may be stricter about certificate contents (e.g. see 1744b66 - this required the CA cert to have
Yes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is quite a big change. I've mostly added nits and some form comments here.
My biggest gripe with it is that library/session config is somewhat different between OSSL/gnutls. The latter uses a single string for config, OSSL is more complicated.
A caller needs to know which impl is used, and adjust his code accordingly.
It makes for more potential bugs when a dev somewhere changes things in one impl, but misses to do it in the other. I.e. we need to make sure CI tests both properly.
@@ -335,6 +335,7 @@ module : private; | |||
#include <seastar/net/virtio.hh> | |||
|
|||
#include "net/native-stack-impl.hh" | |||
#include "net/tls-impl.hh" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this included here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is necessary for when compiling with modules enabled
src/net/tls-impl.hh
Outdated
public: | ||
static std::unique_ptr<connected_socket_impl> get(connected_socket s) { | ||
return std::move(s._csi); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to me this should be just declaration, with impl in impl.cc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was just moved from tls.cc
to this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. But that was a cc. This is a header.
src/net/tls-impl.hh
Outdated
if (_session && _session.use_count() == 1) { | ||
_session->close(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same goes for things like this...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above. Code should not be in headers if it can be avoided (even internal, not very included ones)
include/seastar/net/tls.hh
Outdated
@@ -202,13 +212,53 @@ namespace tls { | |||
|
|||
// TODO add methods for certificate verification | |||
|
|||
#ifndef SEASTAR_USE_OPENSSL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit of a negative check. Should this not be SEASTAR_USE_GNUTLS
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's actually not set as a compile definitions, but I think it should be. Needs to be added to target_compile_definitions
in CMakeLists.txt
. I'll make that update.
src/net/ossl.cc
Outdated
|
||
// This call is required to lower SSL's security level to permit TLSv1.0 and TLSv1.1 | ||
// See https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_security_level.html | ||
SSL_CTX_set_security_level(ssl_ctx.get(), 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be unconditional? In the gnutls impl, allowing or not allowing TLS versions is controlled by the prio string. You check min/max version above, does the level always need lowering?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll experiment with this and get back to you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did a little bit of research on this function and what the level controls changes depending on the version of OpenSSL.
For OpenSSL 3.0, setting security level to 3 disables TLS1.0 and below, and setting it to 4 disables TLS1.1 and below (ref).
Starting with OpenSSL 3.1, level 1 disables TLS1.1 and below (ref).
src/net/tls-impl.cc
Outdated
#endif | ||
|
||
#ifdef SEASTAR_USE_OPENSSL | ||
void tls::credentials_builder::set_cipher_string(const sstring& cipher_string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not place these in the openssl impl file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea, I'll move the definitions to the correct source file
tests/unit/tls_test.cc
Outdated
@@ -161,7 +163,29 @@ SEASTAR_TEST_CASE(test_x509_client_with_builder_system_trust_multiple) { | |||
}); | |||
} | |||
|
|||
static void set_priority_string(tls::credentials_builder & b, const sstring & prio, [[maybe_unused]] bool is_tls_v13 = false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please break this into two (or three) distinct functions and adjust call sites instead. Calling this set_prio more amplifies the issue with library configuration not being equivalent between openssl and gnutls, and is more confusing (imho) at the call sites than just doing different things to accomplish roughly the same.
/* | ||
* Copyright 2015 Cloudius Systems | ||
*/ | ||
#pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this file in public header dir? Seems to me it should only be required by internal compilation units, so should probably be under src.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not in the public header directory, it's in src/net
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doh, sorry, github confused me.
src/net/ossl.cc
Outdated
// This function waits for the _output_pending future to resolve | ||
// If an error occurs, it is saved off into _error and returned | ||
future<> wait_for_output() { | ||
_logger.trace("wait_for_output"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why invent a new logger type when you could just add a formatter for the session object that pretty-prints the local/remote etc, and then just use tls_log::trace("{} wait_for_output")
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion, great idea!
// during the handshake before the client has fully | ||
// closed its connection, then the get() call will | ||
// succeed by return an empty buffer indicating EOF | ||
BOOST_REQUIRE(res.size() == 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a good change, but not related to the rest of the PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test was being flaky when using OpenSSL. It would pass reliably in release but not in debug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, might want to use BOOST_REQUIRE_EQUAL()
for better postmortem debugging experience. as Boost.Test prints out the lhs and rhs of the comparison f the check fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was the test enshrining incorrect behavior?
The different configuration options mean one of two:
So I think we should choose one implementation, and deprecate the other after a transition period. gnutls was chosen due to funky licensing and an unstable API from openssl, but I think that's behind us now. Given that, it's better to use the leader in the field rather than a follower. |
GnuTLS is not FIPS enabled, if compiled with it? (I see https://www.gnutls.org/manual/html_node/FIPS140_002d2-mode.html ) - what's missing? |
The FIPS flag for GnuTLS means that GnuTLS will work in a FIPS compliant way (e.g. rejecting any non FIPS approved crypto like DES or GOST), however that doesn't mean that its implementation was validated. GnuTLS doesn't provide a path to build it and maintain validation, OpenSSL does (see above links to OpenSSL's security policy). |
While I can somewhat sympathize with the sentiment, this would effectively mean dropping the way we handle TLS config for clients/applications (i.e. usage of the prio string). Since at least one database application I know of exposes this in its customer config, you'd effectively be asking to require changing all customer TLS configs where such a prio is applied. Not sure how many they are and how complicated the configs are. You said a transition period, but not sure how to handle this, nor enforce a config migration with clients? |
I would not want to force a config migration. Claude says this:
|
Yes, but I am honestly very nervous about writing/maintaining a prio string translator. The mapping is not just cipher to cipher etc, it is a state machine in itself, disabling and adding ciphers, exchange modes etc. |
I agree with that. @tzach do you have any insight about priority string configuration across our fleet? Do we ever diverge from the default? |
Since we did not disable TLSv1.1 by default (not sure why), there's a good chance users do it - https://enterprise.docs.scylladb.com/stable/operating-scylla/security/client-node-encryption.html#priority-string-and-tlsv1-2-1-3-support |
5c709c2
to
fc616ee
Compare
Force push
|
fc616ee
to
1a53361
Compare
Force push
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks ok, but again, I doubt I can really verify it just by looking. :-(
One huge downside with the openssl code is that imho it seems to make the interface code even cludgier - perhaps partially an aspect of the code it needs to emulate is from a gnutls universe, but I would still argue that a lot of the gnutls interfaces are a bit nicer.
Thus I would worry a little about maintenance here.
src/net/tls-impl.hh
Outdated
public: | ||
static std::unique_ptr<connected_socket_impl> get(connected_socket s) { | ||
return std::move(s._csi); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. But that was a cc. This is a header.
src/net/tls-impl.hh
Outdated
if (_session && _session.use_count() == 1) { | ||
_session->close(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above. Code should not be in headers if it can be avoided (even internal, not very included ones)
void set_session_resume_mode(session_resume_mode); | ||
void set_priority_string(const sstring&); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a gratuitous change?
include/seastar/net/tls.hh
Outdated
@@ -235,6 +247,12 @@ namespace tls { | |||
template<typename Base> | |||
friend class reloadable_credentials; | |||
shared_ptr<impl> _impl; | |||
|
|||
// The following methods are provided so classes that inherity from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: inherit
src/net/ossl.cc
Outdated
auto dn = extract_dn_information(); | ||
if (dn) { | ||
std::string_view stat_str_view{stat_str}; | ||
if (stat_str_view.ends_with(" ")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I assume this is an openssl quirk of some sort? Maybe a while instead (instead of assuming just one space), or maybe even a proper back and front whitespace strip?
src/net/ossl.cc
Outdated
} | ||
|
||
auto & min_tls_version = _creds->minimum_tls_version(); | ||
auto & max_tls_version = _creds->maximum_tls_version(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: space between type and ref.
src/net/ossl.cc
Outdated
} | ||
} | ||
|
||
auto get_min_level = [&ssl_ctx]() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Should be "max level" really, as we should consider us setting the max level we can use given the tls version bounds.
src/net/ossl.cc
Outdated
BIO_METHOD* get_method() { | ||
static thread_local bio_method_ptr method_ptr = [] { | ||
auto ptr = tls::create_bio_method(); | ||
if (!ptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems redundant - all paths in create throws if failed...
src/websocket/server.cc
Outdated
@@ -126,6 +130,30 @@ future<> connection::process() { | |||
|
|||
static std::string sha1_base64(std::string_view source) { | |||
unsigned char hash[20]; | |||
|
|||
#ifdef SEASTAR_USE_OPENSSL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we instead make the function an external/internal-header-decl, and move the full impl into gnutls/openssl compilation units? This just adds to an already bad separation of concern/api exposure.
1a53361
to
2f935ca
Compare
Force push
|
CMakeLists.txt
Outdated
set(Seastar_USE_GNUTLS OFF) | ||
else() | ||
set(Seastar_USE_GNUTLS ON) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you please add space after set
and else
? just to be consistent with the rest of this CMake script.
* under the License. | ||
*/ | ||
/* | ||
* Copyright 2015 Cloudius Systems |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
src/net/ossl.cc
Outdated
@@ -79,6 +79,8 @@ module seastar; | |||
#include "net/tls-impl.hh" | |||
#endif | |||
|
|||
template <> struct fmt::formatter<seastar::tls::session> : fmt::ostream_formatter {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it possible to implement the specialization of fmt::fornmatter<seastar::tls::session>
without the operator<<
? it would be better if we can avoid adding more operator<<
, for two reasons:
- avoid adding the unused
operator<<
- avoid the overhead of using a temporary ostream for formatting
seastar::tls::session
.
src/net/ossl.cc
Outdated
} | ||
|
||
template<> | ||
struct fmt::formatter<seastar::ossl_errc> : public fmt::formatter<std::string_view> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of inheriting from fmt::formatter<std::string_view>
, i'd suggest inheriting from fmt::formatter<string_view>
. please see scylladb/scylladb@168ade7 for more details. we switched from this approach to the proposed one in the referenced commit in scylladb a while ago.
src/net/ossl.cc
Outdated
@@ -770,6 +772,8 @@ class session : public enable_shared_from_this<session>, public session_impl { | |||
session(session_type t, shared_ptr<tls::certificate_credentials> creds, | |||
std::unique_ptr<net::connected_socket_impl> sock, tls_options options = {}) | |||
: _sock(std::move(sock)) | |||
, _local_address(fmt::format("{}", _sock->local_address())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, could use fmt::to_string(_sock->local_address())
instead. simpler this way. and slightly more performant.
src/net/ossl.cc
Outdated
@@ -770,6 +772,8 @@ class session : public enable_shared_from_this<session>, public session_impl { | |||
session(session_type t, shared_ptr<tls::certificate_credentials> creds, | |||
std::unique_ptr<net::connected_socket_impl> sock, tls_options options = {}) | |||
: _sock(std::move(sock)) | |||
, _local_address(fmt::format("{}", _sock->local_address())) | |||
, _remote_address(fmt::format("{}", _sock->remote_address())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto.
src/net/ossl.cc
Outdated
session.get_type_string(), | ||
session.local_address(), | ||
session.remote_address()); | ||
return os; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as explained above, i'd prefer avoid adding more operator<<
overloads unless they are actually necessary and used.
src/net/ossl.cc
Outdated
return make_ready_future(); | ||
} | ||
return _in.get() | ||
.then([this](buf_type buf) { | ||
// Set EOF if it's empty | ||
tls_log.debug("{} wait_for_input: buffer {}empty", *this, buf.empty() ? "is ": ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't really understand this logging message:
- if
buf
is empty, we print "wait_for_input: buffer is empty" -- looks good - if
buf
is not empty, we print "wait_for_input: buffer empty" -- what does this mean? shall we print "wait_for_input: buffer is not empty" or "wait_for_input: buffer not empty" instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that was my mess up. Fixing it
mode: debug | ||
enables: --enable-cxx-modules | ||
enable-ccache: false | ||
crypto_provider: OpenSSL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
piggyback the tests with OpenSSL / GnuTLS might not be a great idea. because, we only enable the test step in
seastar/.github/workflows/test.yaml
Lines 110 to 112 in 613d8b3
- name: Test | |
if: ${{ ! contains(inputs.enables, 'cxx-modules') }} | |
run: ./test.py --mode=${{ inputs.mode }} |
tests.yaml
for building with the OpenSSL backend, and keep the existing job of build_with_cxx_modules
intact.
please allow me to provide more context here: because C++20 modules is currently an experimental feature, not all Seastar facilities are exposed as in the "seastar" C++20 module at this moment, and we only have a single "hello_cxx_module" test for testing the build with C++20 module. none of the unit tests is built with the "seastar" C++20 module at the time of writing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if "cxx-modules" is not enabled. in other words, these two jobs do not run any of the unit tests.
understood
so i'd suggest adding a dedicated job in tests.yaml for building with the OpenSSL backend, and keep the existing job of build_with_cxx_modules intact.
I did this to ensure that the changes I made to implement OpenSSL (namely the addition of ossl.cc
) would build when modules were enabled. Completely understand that the tests are not built.
cab469f
to
47dfb11
Compare
Force push 47dfb11:
|
Note test failures. I'm conflicted here. On the one hand, the tls implementation has a user footprint in priority string or equivalent openssl config. On the other hand, that's a tiny difference and they're otherwise equivalent. OpenSSL would be my choice as the only supported library if there wasn't the user facing stuff. Can we translate the priority string to openssl config? I asked Claude and it spewed a long python script, maybe that's good enough. |
It appears all failures are from
It definitely could be done by setting all of these within an OpenSSL config file. You'd just have to be careful to tell OpenSSL where to find it so it doesn't attempt to locate and use the system default one (unless that's desired). |
I guess your question is "can I take the input to |
Is there no equivalent textual configuration? I wouldn't want to maintain it, but neither do I want to maintain two different tls implementations. |
AFAIK only through the OpenSSL config file which can be loaded either automatically by OpenSSL when it is initialized or can be controlled by the user by calling |
Created tls-impl.cc and tls-impl.h which contains common structures and definitions that are not dependent on the underlying TLS mechanism. These changes set the stage for implementing other TLS providers. Signed-off-by: Michael Boquard <michael@redpanda.com>
This commit adds support for using OpenSSL, instead of GnuTLS, as the TLS provider within Seastar. To support this change, the configure script has been updated to allow users to select which cryptographic provider should be used by supply `--crypto-provider` and specificying either `OpenSSL` or `GnuTLS`. The OpenSSL implementation mirrors the GnuTLS implementation. Instead of using callbacks, a custom BIO was created to handle moving data on/off of the OpenSSL SSL session into the Seastar TLS session data sinks. When compiled for OpenSSL, the `certificate_credentials::set_priority_string` method is compiled out and replaced with the following: * `set_cipher_string` * `set_ciphersuites` * `enable_server_precedence` * `set_minimum_tls_version` * `set_maximum_tls_version` These methods are specific to OpenSSL. The github actions have been updated to run the full suite of tests against both cryptographic providers. `src/net/tcp.hh` and `src/websocket/server.cc` have been updated to use OpenSSL instead of GnuTLS, depending upon the build configuration. Signed-off-by: Michael Boquard <michael@redpanda.com>
Added pretty-print capabilities to seastar::tls::session for OpenSSL and added a number of log statements that may be helpful if debugging the implementation. Signed-off-by: Michael Boquard <michael@redpanda.com>
More recent versions of OpenSSL requrire CA certificates to have CA:true Signed-off-by: Michael Boquard <michael@redpanda.com>
Now handling situations where the get() call doesn't throw but does return an empty buffer indicating EOF. Signed-off-by: Michael Boquard <michael@redpanda.com>
TLS renegotiation was removed in TLSv1.3 due to issues around security. This change makes that the default behavior, however a method is exposed to re-enable it if desired. This was only added to OpenSSL as GnuTLS does not provide a means to fully disable renegotiation. Signed-off-by: Michael Boquard <michael@redpanda.com>
47dfb11
to
63027a1
Compare
Hi again @avikivity and @elcallio . Apologies for such a long delay in updating this PR. I've made some updates and rebased off of master. |
Hi again @avikivity and @elcallio . Was wondering if there was anything I could do to assist in regards to this PR? |
I prefer replacing gnutls with openssl rather than adding yet another option. But perhaps we can't due to those minor configuration issues. Maybe we can start a long deprecation cycle during which users will be encouraged to update their configuration. |
If we indeed start a deprecation cycle, it will have to be run-time selectable (so users can update their configuration, change the selector, restart). I don't know how difficult that is. |
From an API standpoint, I guess replacing the prio strings with some sort of abstracted algorithm-selection is the biggest hurdle (std::set<tls_algo> allow, forbid?). Once users migrate this, the rest should be fairly transparent/equivalent. |
virtual future<session_data> get_session_resume_data() = 0; | ||
virtual future<std::vector<certificate_data>> get_peer_certificate_chain() = 0; | ||
virtual future<std::optional<sstring>> get_selected_alpn_protocol() = 0; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this is easy to make run-time (start-time) selectable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lack of virtual destructor is justified by shared_ptr below, but please add a comment.
But: is shared_ptr called for? why not unique_ptr or lw_shared_ptr? Who's sharing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Input and output.
session_ref& operator=(const session_ref&) = default; | ||
|
||
shared_ptr<session_impl> _session; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using session_ref =
would be sufficient, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is in current TLS impl. and no. The session ref has a special property that if it is the last one to release the session (i.e. it will cause destruct), it "resurrects" the session and creates a background BYE handshake cycle.
}; | ||
|
||
class tls_connected_socket_impl : public net::connected_socket_impl, public session_ref { | ||
public: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is-a relationship between tls_connected_socket_impl and session_ref?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it needs to create input/output sinks when asked.
class tls_connected_socket_impl::source_impl: public data_source_impl, public session_ref { | ||
public: | ||
using session_ref::session_ref; | ||
private: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see where the sharing comes from. But lw_shared_ptr is sufficient. Or keep a reference to the connected_socket_impl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
socket_impl is stored with a unique ptr -> cannot be shared. Our IO design allows the input/output streams to exists independently of the creating socket. Thus the need to share the underlying session.
|
||
#ifdef SEASTAR_USE_OPENSSL | ||
/** | ||
* Used to set the cipher string for TLS versions 1.2 and below |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are to co-support the two implementations, then we should always compile these, but throw something instead. Maybe std::bad_cast (we're "casting" gnutls to openssl or something).
* for documentation on the format of the ciphersuites string. | ||
*/ | ||
void set_ciphersuites(const sstring&); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::string_view is more flexible.
@@ -629,6 +685,12 @@ namespace tls { | |||
extern const int ERROR_NO_CIPHER_SUITES; | |||
extern const int ERROR_DECRYPTION_FAILED; | |||
extern const int ERROR_MAC_VERIFY_FAILED; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are those error numbers compatible? And specified somewhere?
sstring _ciphersuites; | ||
bool _enable_server_precedence = false; | ||
std::optional<tls_version> _min_tls_version; | ||
std::optional<tls_version> _max_tls_version; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's package those in openssl/gnutls sub-structs.
@@ -0,0 +1,2288 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use "openssl.cc" to make it immediately understood.
// sufficiently large enough to avoid collision with OpenSSL BIO controls | ||
#define BIO_C_SET_POINTER 1000 | ||
// Index into ex data for SSL structure to fetch a pointer to session | ||
#define SSL_EX_DATA_SESSION 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use C++ constexpr variables instead.
Introduces OpenSSL as an alternative TLS implementation to GnuTLS. This is a build-time configuration controlled by the CMake variable
Seastar_USE_OPENSSL
. Theconfigure.py
script has been updated to now have a--crypto-provider
option. Valid arguments to that areOpenSSL
andGnuTLS
.This implementation was released in Redpanda v24.2 on July 31st, and has been running on production clusters since.
Redpanda implemented these changes in order to provide a FIPS-compliant build to customers that require it (such as those wishing to undergo FedRAMP evaluation). OpenSSL was selected as it allows implementors to maintain the validation of the cryptographic module even when it's built from source.
modules
No changes have been introduced to enable the FIPS provider for Seastar. It is up to the implementor to enable and use the FIPS cryptographic module if desired.
Fixes: #698